package uiao.step5_transaction_proxy;

import uiao.step3_connection_holder.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TransactionEnabledProxyManager {
    private TransactionManager transactionManager;

    public TransactionEnabledProxyManager(TransactionManager transactionManager) {

        this.transactionManager = transactionManager;
    }

    /**
     * object 为要执行反射操作的对象
     *
     * @param object
     * @return
     */
    public Object proxyFor(Object object) {
        // 第一个参数为对象的类加载器，第二个参数为这个对象所实现的接口的类型
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new TransactionInvocationHandler(object, transactionManager));
    }
}

class TransactionInvocationHandler implements InvocationHandler {
    private Object proxy;
    private TransactionManager transactionManager;


    /**
     * @param object             在使用反射时需要把真正执行方法的对象object通过构造方法传进来
     * @param transactionManager
     */
    TransactionInvocationHandler(Object object, TransactionManager transactionManager) {
        this.proxy = object;
        this.transactionManager = transactionManager;
    }

    /**
     * @param o       这个参数一半没什么作用
     * @param method
     * @param objects
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        transactionManager.start();
        Object result = null;
        try {
            result = method.invoke(proxy, objects);
            transactionManager.commit();
        } catch (Exception e) {
            System.out.println("回滚");
            transactionManager.rollback();
        } finally {
            transactionManager.close();
        }
        return result;
    }
}
